/*****************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work
 * for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License. You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations
 * under the License.
 ****************************************************************/
package reco.db

import static org.mockito.Mockito.mock
import static com.google.common.collect.Iterables.*
import org.mockito.Mockito;

description "Verifies that field state can be changed in any way before it is marked as 'defined' with definitionComplete()"

before "init a field under definition", {
    given "a field under definition", {
        field = new DummyField();
        field.name = "field"
        field.domain = DummyDomain
        field.defaultValue = "default"
    }
}

scenario "change field's name", {    
    when "field's name is modified", {
        defineNameOf = { field -> field.name = "field name" }
    }
    
    then "the field name should be updated", {
        defineNameOf(field)
        field.name.shouldBe "field name"
    }
}

scenario "change field's domain", {
    when "field's domain is modified", {
        defineDomainOf = { field -> field.domain = DummyDomain }
    }
    
    then "field's domain should be updated", {
        defineDomainOf(field)
        field.domain.shouldBe DummyDomain
    }
}

scenario "change field's default value", {
    when "field's default value is modified", {
        defineDefaultValueOf = { field -> field.defaultValue = "default" }
    }
    
    then "field's default value should be updated", {
        defineDefaultValueOf(field)
        field.defaultValue.shouldBe "default"
    }
}

scenario "add a constraint to the field", {
    given "a constraint definition", {
        constraintDefinition = mock(ConstraintFactory)
        constraint = mock(Constraint)
        Mockito.when(constraintDefinition.createConstraintFor(field)).thenReturn(constraint)
    }
    
    when "attach the constraint definition to the field", {
        field.addConstraint(constraintDefinition)
    }
    
    then "the field should have a constraint that corresponds with the definition attached", {
        contains(field.constraints(), constraint).shouldBe true 
    }
}